﻿namespace LogManager.Gui.Views.Templates
{
    using System;
    using System.Collections.Generic;
    using System.Threading.Tasks;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Media.Animation;
    using LogManager.Gui.FrameworkExtensions;

    public partial class PageTransition : UserControl
    {
        private Stack<IFrameworkElement> pages = new Stack<IFrameworkElement>();

        public IFrameworkElement CurrentPage { get; private set; }

        public static readonly DependencyProperty StoryBoardInProperty = DependencyProperty.Register(
        "StoryBoardIn", // propertyname
        typeof(Storyboard),// propertytype
        typeof(PageTransition), // owernertype
       new UIPropertyMetadata(null));

        public Storyboard StoryBoardIn
        {
            get
            {
                return (Storyboard)GetValue(StoryBoardInProperty);
            }
            set
            {
                SetValue(StoryBoardInProperty, value);
            }
        }

        public static readonly DependencyProperty StoryBoardOutProperty = DependencyProperty.Register(
        "StoryBoardOut", // propertyname
        typeof(Storyboard),// propertytype
        typeof(PageTransition), // owernertype
        new UIPropertyMetadata(null));

        public Storyboard StoryBoardOut
        {
            get
            {
                return (Storyboard)GetValue(StoryBoardOutProperty);
            }
            set
            {
                SetValue(StoryBoardOutProperty, value);
            }
        }


        public PageTransition()
        {
            InitializeComponent();
        }

        public void ShowPage(IFrameworkElement newPage)
        {
            CurrentPage = newPage;

            if (newPage != null)
            {
                pages.Push(newPage);
            }

            Task.Factory.StartNew(() => ShowNewPage());
        }

        private void ShowNewPage()
        {
            Dispatcher.Invoke((Action)delegate
                {
                    if (contentPresenter.Content != null)
                    {
                        var oldPage = contentPresenter.Content as IFrameworkElement;

                        if (oldPage != null)
                        {
                            oldPage.Loaded -= newPage_Loaded;

                            UnloadPage(oldPage);
                        }
                    }
                    else
                    {
                        ShowNextPage();
                    }

                });
        }

        void ShowNextPage()
        {
            if (pages.Count == 0)
            { return; }

            IFrameworkElement newPage = pages.Pop();
            newPage.Loaded += newPage_Loaded;
            contentPresenter.Content = newPage;
        }

        void UnloadPage(IFrameworkElement page)
        {
            if (StoryBoardOut != null)
            {
                StoryBoardOut.Completed += hidePage_Completed;
                StoryBoardOut.Begin(contentPresenter);
            }
            else
            {
                hidePage_Completed(null, null);
            }
        }

        void newPage_Loaded(object sender, RoutedEventArgs e)
        {
            if (StoryBoardIn != null)
            {
                StoryBoardIn.Begin(contentPresenter);
            }
        }

        void hidePage_Completed(object sender, EventArgs e)
        {
            contentPresenter.Content = null;

            ShowNextPage();
        }
    }
}
